﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

using eCitizen.eAlerts.Constants;
using eCitizen.DataContracts;
using eCitizen.DataAccess;


namespace eCitizen.eAlerts.BusinessService
{
    public class StatusReportManager: ServiceBase
    {
        private DateTime _statusReportDate;

        public StatusReportManager(DateTime statusReportDate)
        {
            _statusReportDate = statusReportDate;
        }

        public void LogSmsStatusReport(SmsStatusReport statusReport)
        {
            ReportLoggingService messageLogService = new ReportLoggingService();
            messageLogService.LogSmsSendStatus(statusReport);
        }

        public EmailStatusReport GetEmailStatusReport(EmailStatusReport emailReport)
        {
           return new ReportLoggingService().GetEMailStatusReport(emailReport);
        }

        #region "Send Reports"

        public ServiceRequest SendSubscriptionReport(List<Subscriber> subscriberList)
        {
            // Need to send two files
            ServiceRequest currentFileRequest = new ServiceRequest();

            // Get the SubscriberReport file
            string reportFileName = FormSubscriberStatusReportName();
            string reportFileContent = FormSubscriptionReportContent(subscriberList);

            WritetoFile(reportFileName, reportFileContent);

            // Get the SubscriberReport Checksum file
            string checksumFileName = FormSubscriberStatusChecksumName();
            string checksumFileContent = FormSubscriptionChecksumContent(subscriberList);


            WritetoFile(checksumFileName, checksumFileContent);

            currentFileRequest.RequestFileName = reportFileName;
            currentFileRequest.ChecksumFileName = checksumFileName;

            return currentFileRequest;

        }

        public ServiceRequest SendSubscriberProfileReport(List<Subscriber> subscriberList)
        {
            ServiceRequest currentFileRequest = new ServiceRequest();

            string reportFileName = FormSubscriberProfileReportName();
            string reportFileContent = FormSubscriberProfileReportContent(subscriberList);

            WritetoFile(reportFileName, reportFileContent);

            // Get the SubscriberReport Checksum file
            string checksumFileName = FormSubscriberProfileChecksumName();
            string checksumFileContent = FormSubscriptionChecksumContent(subscriberList);

            WritetoFile(checksumFileName, checksumFileContent);

            currentFileRequest.RequestFileName = reportFileName;
            currentFileRequest.ChecksumFileName = checksumFileName;

            return currentFileRequest;

        }

        public void SendSmsStatusReport(List<ServiceRequest> requestFiles)
        {
            string reportFileName = null;

            foreach (ServiceRequest requestFile in requestFiles)
            {
                
                reportFileName = FormSmsStatusReportName(requestFile.RequestFileName);
                WritetoFile(reportFileName, requestFile.RequestFile);
            }
        }

        public ServiceRequest SendEmailStatusReport(EmailStatusReport emailReport)
        {

            ServiceRequest fileName = new ServiceRequest();

            string reportFileName = FormEmailStatusReportName(emailReport);
            string reportFileContent = FormEmailReportContent(emailReport);

            fileName.RequestFileName = reportFileName;

            WritetoFile(reportFileName, reportFileContent);

            return fileName;

        }

        #endregion

        #region "Form Report File Names"
        private string FormEmailStatusReportName(EmailStatusReport emailReport)
        {
            string format = AppKeyConstants.EmailOutputReportFileFormat;
            string fileName;

            fileName = string.Format(format, emailReport.Agency, emailReport.ServiceId, emailReport.ReportDate.ToString(ServiceConstants.DateFormats.YYYYMMDD));
            fileName = CurrentConfiguration.GetLocalOutboxFolder() + "\\" + fileName;

            return fileName;

        }

        private string FormSmsStatusReportName(string requestFileName)
        {

            string fileName = CurrentConfiguration.GetLocalSmsOutboxFolder() + "\\" + requestFileName;

            return fileName;
        }

        private string FormSubscriberStatusReportName()
        {
            string format = AppKeyConstants.SubscriberOutputReportFileFormat;
            string fileName;

            fileName = string.Format(format, _statusReportDate.ToString(ServiceConstants.DateFormats.YYYYMMDD), CurrentConfiguration.Agency, CurrentConfiguration.Service);
            fileName = CurrentConfiguration.GetLocalOutboxFolder() + "\\" + fileName;

            return fileName;
        
        }

        private string FormSubscriberStatusChecksumName()
        {
            string format = AppKeyConstants.SubscriberOutputChecksumFileFormat;
            string fileName;

            fileName = string.Format(format, _statusReportDate.ToString(ServiceConstants.DateFormats.YYYYMMDD), CurrentConfiguration.Agency, CurrentConfiguration.Service);
            fileName = fileName = CurrentConfiguration.GetLocalOutboxFolder() + "\\" + fileName;

            return fileName;
        }

        private string FormSubscriberProfileReportName()
        {
            string format = AppKeyConstants.SubscriberProfileReportFileFormat;
            string fileName;

            fileName = string.Format(format, _statusReportDate.ToString(ServiceConstants.DateFormats.YYYYMMDD), CurrentConfiguration.Agency, CurrentConfiguration.Service);
            fileName = CurrentConfiguration.GetLocalOutboxFolder() + "\\" + fileName;

            return fileName;
        }

        private string FormSubscriberProfileChecksumName()
        {
            string format = AppKeyConstants.SubscriberProfileChecksumFileFormat;
            string fileName;

            fileName = string.Format(format, _statusReportDate.ToString(ServiceConstants.DateFormats.YYYYMMDD), CurrentConfiguration.Agency, CurrentConfiguration.Service);
            fileName = CurrentConfiguration.GetLocalOutboxFolder() + "\\" + fileName;

            return fileName;
        }

        #endregion

        #region "Form Report File Content"

        private string FormSubscriptionReportContent(List<Subscriber> subscriberList)
        {
            StringBuilder reportBuilder = new StringBuilder();

            foreach (Subscriber subscriberInfo in subscriberList)
            {
                reportBuilder.AppendLine(subscriberInfo.NRIC);
            }

            if (subscriberList.Count == 0) reportBuilder.Append(string.Empty);
            return reportBuilder.ToString().TrimEnd('\r', '\n');
        }

        private string FormSubscriptionChecksumContent(List<Subscriber> subscriberList)
        {
            return subscriberList.Count().ToString().TrimEnd('\r', '\n');
        }

        private string FormSubscriberProfileReportContent(List<Subscriber> subscriberList)
        {
            StringBuilder reportBuilder = new StringBuilder();

            foreach (Subscriber subscriberInfo in subscriberList)
            {

                string subsciberProfile = string.Empty;

                subsciberProfile = subscriberInfo.NRIC + ",";

                subsciberProfile += subscriberInfo.Gender.ToString() + ",";

                subsciberProfile += subscriberInfo.DateOfBirth.ToString(ServiceConstants.DateFormats.StandardFormat) + ",";

                subsciberProfile += subscriberInfo.MaritalStatus.ToString() + ",";

                subsciberProfile += subscriberInfo.ResidentialStatus.ToString() + ",";

                subsciberProfile += subscriberInfo.EmploymentStatus.ToString();

                reportBuilder.AppendLine(subsciberProfile);

            }

            if (subscriberList.Count == 0) reportBuilder.Append(string.Empty);
            return reportBuilder.ToString().TrimEnd('\r', '\n');
        }
        

        private string FormEmailReportContent(EmailStatusReport emailReport)
        {
            StringBuilder reportBuilder = new StringBuilder();
            string reportFileFormat = "{0},{1},{2}";

            // Check if there is any Status Report on the day
            if (emailReport.EmailStatusRecords.Count > 0)
            {
                // Have one or more Status Record
                foreach (EmailStatus statusRecord in emailReport.EmailStatusRecords)
                {
                    string reportLine = String.Format(reportFileFormat, emailReport.Agency, emailReport.ServiceId, statusRecord.TotalSuccessful);
                    reportBuilder.AppendLine(reportLine);
                }
            }
            else
            { 
                // No Status Record
                string reportLine = String.Format(reportFileFormat, emailReport.Agency, emailReport.ServiceId, emailReport.EmailStatusRecords.Count);
                reportBuilder.AppendLine(reportLine);
            }

            return reportBuilder.ToString().TrimEnd('\r', '\n');
        }
       
        #endregion

        private void WritetoFile(string fileName,string fileContent)
        {
            string directory = Path.GetDirectoryName(fileName);
            if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
            TextWriter writer = new StreamWriter(fileName);

            writer.Write(fileContent);

            writer.Close();
        }

        private void WritetoFile(string fileName, StreamReader fileContent)
        {
            string directory = Path.GetDirectoryName(fileName);
            if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);

            TextWriter writer = new StreamWriter(fileName);

            fileContent.BaseStream.Position = 0;
            writer.Write(fileContent.ReadToEnd());

            writer.Close();
        }

    }
}
